Skip to content

Dogfood dotnet test for Mono.Android device tests#11224

Merged
jonathanpeppers merged 81 commits into
mainfrom
jonathanpeppers/dogfood-dotnet-test
Jun 10, 2026
Merged

Dogfood dotnet test for Mono.Android device tests#11224
jonathanpeppers merged 81 commits into
mainfrom
jonathanpeppers/dogfood-dotnet-test

Conversation

@jonathanpeppers

@jonathanpeppers jonathanpeppers commented Apr 27, 2026

Copy link
Copy Markdown
Member

Summary

Migrate Mono.Android device test infrastructure from the legacy NUnitLite stack to dotnet test with the Microsoft Testing Platform (MTP), following the pattern established for the androidtest template in 031246d.

Callers now run device tests with stock dotnet test, no custom MSBuild targets required. NUnitLite is removed entirely from the workload — both as a framework assembly and as a vendored copy.

Changes

New: MTP-based TestInstrumentation base class

  • tests/TestRunner.Core/TestInstrumentation.cs is now an MTP-based on-device runner using stock NUnit (NUnitTestAssemblyRunner) plus Microsoft.Testing.Platform.
  • Mirrors the androidtest template: tests run synchronously on the instrumentation thread (NumberOfTestWorkers = 0, see comment in code), TRX is written to the app data dir, and the path is sent back through the instrumentation bundle so the host adapter can pick it up.

Updated test projects

  • Mono.Android.NET-Tests, Java.Interop-Tests, JcwGen-Tests: now reference stock NUnit 3.13.3 from NuGet (no NUnitLite / TestRunner.NUnit), set IsTestingPlatformApplication=true, and use the new TestInstrumentation base.

Deleted (~41K lines)

  • src/Xamarin.Android.NUnitLite/ — the Xamarin.Android.NUnitLite.dll framework assembly (NUnitLite wrapper, TestSuiteInstrumentation, GUI TestSuiteActivity / TestResultActivity / OptionsActivity, layouts).
  • src-ThirdParty/NUnitLite/ — the embedded NUnitLite source we used to compile into the above.
  • tests/TestRunner.NUnit/NUnitTestRunner / NUnitTestInstrumentation.
  • tests/TestRunner.xUnit/XUnitTestRunner / XUnitTestInstrumentation.
  • Xamarin.Android.NUnitLite.dll/.pdb/.xml removed from build-tools/installers/create-installers.targets (no longer shipped in the framework).
  • Various custom RunTestApp / device-test MSBuild targets.

The XA4313 deprecation message in Common.targets (which suggested customers migrate Xamarin.Android.NUnitLiteXamarin.Legacy.NUnitLite) is preserved as the existing escape hatch; the Xamarin.Legacy.NUnitLite NuGet is published from a separate repo and is unaffected by these changes.

NativeAOT trimmer fix

NUnit 3.13.3's EquatablesComparer walks every value via reflection: type.GetInterfaceMap(typeof(IEquatable<T>)) then MethodInfo.Invoke on the result. Under stock NativeAOT this throws Arg_NotSupportedException because ILC strips the dispatch-slot mapping. NUnit 3.14+ guards this with try/catch, but we cannot bump globally (it regresses the Mono Interpreter AwaitAdapter lane).

Real fix, no [Category("NativeAOTIgnore")] shortcuts:

  • tests/Mono.Android-Tests/Mono.Android-Tests/Mono.Android.NET-Tests.csproj: under '$(PublishAot)' == 'true', set <IlcGenerateCompleteTypeMetadata>true</IlcGenerateCompleteTypeMetadata> and pull in a new NativeAOT.rd.xml.
  • tests/Mono.Android-Tests/Mono.Android-Tests/NativeAOT.rd.xml roots the closed IEquatable<T> instantiations the test value types need (String, Boolean, IntPtr, TimeSpan, DateTime) plus the concrete types themselves as Dynamic="Required All", so ILC keeps the slot mapping. Also roots TaskAwaitAdapter+GenericAdapter<VoidTaskResult> for NUnit's async adapter.

Result on CI build 14325032: NativeAOT lane 230 passed / 0 failed (43 legitimate category exclusions).

CI updates (apk-instrumentation.yaml)

  • Build with -t:Install, run with dotnet test --no-build --report-trx.
  • Test results are published as VSTest (TRX) instead of NUnit XML.
  • Added adb logcat -d capture so device-test crashes can be diagnosed without re-running CI.

Test fixes / bookkeeping

  • Centralized JavaSystem.LoadLibrary ("reuse-threads") in TestInstrumentation.OnCreate so it runs on the main Java thread instead of inside individual tests.
  • Synced ExcludedTestNames / ExcludedCategories to match main.

Out of scope

  • EmbeddedDSO and Locale-Tests — old-style csproj that still <Reference Include="Xamarin.Android.NUnitLite" />. They need an SDK migration before this PR can fully delete that assembly's identity from the build (the XA4313 deprecation will fire on these projects today). Tracked separately.

Already split out

These improvements were carved out of this PR and merged separately to main:

Related

@jonathanpeppers jonathanpeppers force-pushed the jonathanpeppers/dogfood-dotnet-test branch from 31e7d49 to 7b8a944 Compare April 27, 2026 21:45
@jonathanpeppers

jonathanpeppers commented Apr 27, 2026

Copy link
Copy Markdown
Member Author

With MTP, test filtering works via command-line args passed to TestApplication.CreateBuilderAsync(). NUnit's MTP adapter supports --treenode-filter which accepts NUnit filter expressions.

I've now added this support to TestInstrumentation. Subclasses can override:

  • ExcludedCategories — to exclude NUnit categories
  • ExcludedTestNames — to exclude tests by fully-qualified name (for Java.Interop submodule tests where adding attributes isn't practical)

The old am instrument extras still work too:

  • -e exclude "Cat1,Cat2" — exclude categories at runtime
  • -e include "Cat1" — include categories at runtime
  • -e noexclusions true — skip built-in exclusions

Everything gets translated to a --treenode-filter expression.

@jonathanpeppers jonathanpeppers force-pushed the jonathanpeppers/dogfood-dotnet-test branch from 04b483b to 8bc3984 Compare May 4, 2026 16:39
jonathanpeppers and others added 18 commits May 5, 2026 10:00
…form (MTP)

- Revamp `TestRunner.Core/TestInstrumentation.cs` to use MTP + NUnit
  (following the androidtest template pattern with `AddNUnit()`)
- Delete `TestRunner.NUnit/`, `TestRunner.xUnit/`,
  `Xamarin.Android.NUnitLite/`, `src-ThirdParty/NUnitLite/`
- Update `Mono.Android.NET-Tests` and `JcwGen-Tests` to use new
  `TestInstrumentation` base class with stock NUnit 4.3.2
- Update CI YAML to use `dotnet test --no-build` instead of
  `-t:RunTestApp`
- Update `NUnitReferences.projitems` to NUnit 4.3.2 + adapter 5.0.0
- Clean up `Directory.Build.props`, installer targets, and solution
  files

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The NUnit 4.x upgrade broke all host-side test projects because NUnit 4
removed classic assert APIs (Assert.IsTrue, FileAssert, etc.).

Only NUnit3TestAdapter 5.0.0 is needed (for AddNUnit() MTP support) in
the device test projects. NUnit itself stays at 3.13.3, and the shared
NUnitReferences.projitems is restored to its original versions.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The publish step was skipped because testResultsFiles was empty.
Add --logger trx and --results-directory to produce TRX files,
and use a deterministic file path for PublishTestResults@2.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Restore XA4313 AndroidError for Xamarin.Android.NUnitLite in Common.targets
- Restore NUnitLite in XA4313 test Values in BuildTest.cs
- Restore GenerateAssemblyInfo=false and AssemblyInfo.cs in TestRunner.Core
- Delete unused MainActivities and Main.axml layout
- Move MyFragment to its own file (still needed by FragmentFixup tests)
- Fix TRX publishing: copy device-pulled TRX to expected path instead
  of relying on --logger trx which doesn't work with Microsoft.Android.Run

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: dotnet test uses VSTest mode by default, which runs
vstest.console to discover tests from DLLs. Android device tests need
MTP mode so dotnet test uses RunCommand/RunArguments to invoke
Microsoft.Android.Run, which runs am instrument on the device.

Changes:
- Add global.json with MTP runner to each device test project directory
  (matches the androidtest template pattern)
- Add IsTestingPlatformApplication=true to device test csprojs so the
  MTP mode of dotnet test recognizes them
- Add GenerateTestingPlatformEntryPoint=false since Android projects
  have their own entry point
- Update apk-instrumentation.yaml to cd into the project directory
  before running dotnet test, so it finds the project-local global.json
- Fix NUnitInstrumentation.cs -> TestInstrumentation.cs in Compile items
- Remove stale TrimmerRootAssembly refs to deleted projects
- Add test exclusion support via ExcludedCategories/ExcludedTestNames

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ComputeRunArguments needs intermediate build outputs (AndroidManifest.xml)
to resolve the package name, and the app must be installed on the device
before Microsoft.Android.Run can invoke am instrument.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This project previously got NUnit transitively via Xamarin.Android.NUnitLite.
Now that NUnitLite is deleted, it needs a direct NUnit reference.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Define NUnitVersion in Configuration.props and reference it everywhere
instead of copying 3.13.3 into each csproj.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
TestRunner.Core.NET.csproj did not import Configuration.props, so
$(NUnitVersion) was empty causing NU1015.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NUnit3TestAdapter targets netcoreapp3.1/net462 which are not compatible
with Android TFMs, so AddNUnit() and MTP types are unavailable on device.

Instead, use NUnitTestAssemblyRunner to run tests directly and generate
TRX output that Microsoft.Android.Run pulls via adb and reports through
MTP on the host side.

Also add NUnit compatibility shim for TestFixtureSetUpAttribute and
TestFixtureTearDownAttribute which were removed from stock NUnit but
are used by Java.Interop submodule test code.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previous edit accidentally removed the <ItemGroup> opening tag around
ProjectReferences when removing NUnit3TestAdapter, leaving orphaned
closing tags that caused Step_GenerateCGManifest XML parse failure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NUnit 3.13.3 filter classes (CategoryFilter, NotFilter, etc.) are
internal. Use TestFilter.FromXml() with NUnit XML filter syntax instead.

Remove [Obsolete] from TestFixtureSetUp/TearDown compatibility shims
since warnings-as-errors treats them as build errors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Mono.Android.NET-Tests project does not have ImplicitUsings enabled,
so explicit using directives are needed for System, System.Collections.Generic,
and Android.OS.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
NUnit 3.13.3 DefaultTestAssemblyBuilder.Build(Assembly, ...) calls
AssemblyHelper.GetAssemblyPath() which accesses Assembly.CodeBase.
On .NET Android, assemblies are in a single-file bundle so CodeBase
throws NotSupportedException.

Fix by using the string-based Load(string, settings) overload with
Assembly.FullName. NUnit resolves this via Assembly.Load(AssemblyName)
which finds the already-loaded assembly without needing CodeBase.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers jonathanpeppers force-pushed the jonathanpeppers/dogfood-dotnet-test branch from 8bc3984 to cec4ac5 Compare May 5, 2026 15:01
jonathanpeppers and others added 4 commits May 5, 2026 14:00
The previous fix (using assembly.FullName with the string-based Load
overload) silently failed — NUnit sets AssemblyName.Name to the full
display name string, which does not resolve to the loaded assembly.

Replace DefaultTestAssemblyBuilder with a custom AndroidTestAssemblyBuilder
that redirects Build(Assembly, ...) through the string overload using
assembly.GetName().Name (simple name). This avoids Assembly.CodeBase
entirely while correctly resolving the already-loaded assembly via
Assembly.Load(AssemblyName).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add --report-trx and --results-directory to dotnet test so MTP
generates a TRX file on the host side. This replaces the fragile
find+copy step that searched $TMPDIR/AndroidTestResults for a
device-pulled TRX file (which was not being found).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…publishing

NUnit 3.13.3 (from NuGet) enforces that TestCaseSource must refer to
static fields. The old bundled NUnitLite allowed instance fields.
Make EncodingTestData, NinePatchDrawables, and AssetPngs static.

Restore ExcludedTestNames for TrimmableTypeMap mode that were in the
old NUnitInstrumentation but missing from the new TestInstrumentation
subclass.

Add --report-trx to dotnet test so MTP generates a TRX file on the
host side for PublishTestResults@2. Remove the broken find+copy step
that was searching $TMPDIR/AndroidTestResults and not finding anything.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The old TestApks.targets passed ExcludeCategories via am instrument -e
extras. AndroidTestAdapter does not support extras, so bake the category
exclusions into the TestInstrumentation subclass using RuntimeFeature
checks instead. This excludes CoreCLRIgnore/NTLM on CoreCLR and
NativeTypeMap/Export on trimmable typemap, matching the old behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers and others added 2 commits May 6, 2026 12:36
…od-dotnet-test

# Conflicts:
#	THIRD-PARTY-NOTICES.TXT
#	tests/Mono.Android-Tests/Mono.Android-Tests/Xamarin.Android.RuntimeTests/NUnitInstrumentation.cs
The --report-trx flag is forwarded by MTP to the test host process
(Microsoft.Android.Run). Without registering the TrxReport extension,
the test host rejects the flag as unknown. Add the
Microsoft.Testing.Extensions.TrxReport package and call
AddTrxReportProvider() so MTP can generate TRX files on the host side.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

jonathanpeppers and others added 2 commits June 9, 2026 08:46
NUnit's EquatablesComparer.GetEquatableImplementations does
i.GetGenericArguments()[0] on every IEquatable<T> a type implements.
Under NativeAOT, the closed-generic-instantiation metadata for
IEquatable<T> gets trimmed, so GetGenericArguments() returns an empty
array and 29 tests die with IndexOutOfRangeException whenever
Assert.AreEqual touches such a type.

Set IlcGenerateCompleteTypeMetadata=true so ILC retains complete
reflection metadata for all reachable types, including the closed
generic instantiations needed by NUnit's reflection-based comparer.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

IlcGenerateCompleteTypeMetadata fixed NUnit's
EquatablesComparer.GetGenericArguments() call, but NUnit then calls
MethodInfo.Invoke on IEquatable<T>.Equals via the *interface*
MethodInfo. NativeAOT requires invocation thunks to be generated for
each closed instantiation, otherwise reflection-invoke fails with
"Object_NotInvokable: no code was generated for it".

Add an rd.xml that declares Dynamic="Required All" for each
IEquatable<T> our Assert.AreEqual callsites need: String, Boolean,
IntPtr, TimeSpan, DateTime.

Same file also keeps NUnit.Framework.Internal.TaskAwaitAdapter+
GenericAdapter<VoidTaskResult>; that instantiation is built via
Type.MakeGenericType for non-generic Task and the trimmer cannot
reach VoidTaskResult statically.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

NUnit 3.13.3 EquatablesComparer.GetEquatableImplementations calls
Type.GetInterfaceMap(IEquatable<T>) on the runtime type, then invokes
the resulting MethodInfo. NativeAOT's GetInterfaceMap walks the
interface methods, asks the VirtualMethodInvoker to resolve the slot
on the instance type, and throws Arg_NotSupportedException if ILC did
not pre-generate the dispatch entry.

Rooting only the IEquatable<T> instantiation (interface side) was not
enough — ILC also needs the concrete instance type (System.String,
System.Boolean, etc.) marked Required All so the slot-to-target
mapping is emitted. Add the five primitive types our Assert.AreEqual
callsites hit on the NativeAOT lane.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines will not run the associated pipelines, because the pull request was updated after the run command was issued. Review the pull request again and issue a new run command.

@jonathanpeppers

Copy link
Copy Markdown
Member Author

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 1 pipeline(s).

jonathanpeppers added a commit that referenced this pull request Jun 9, 2026
* Localized file check-in by OneLocBuild Task (#11610)

Build definition ID 17928: Build ID 14320800

* [xaprepare] Check in `Mono.Android.Apis.projitems`, remove generator (#11608)

`Mono.Android.Apis.projitems` was previously generated at prepare time by
`GeneratedMonoAndroidProjitemsFile` (in xaprepare) from the
`BuildAndroidPlatforms.AllPlatforms` list. Both had exactly one consumer
(each other), so check in the projitems as a source file and drop the
generator plumbing.

Changes:

  * Add `src/Mono.Android/Mono.Android.Apis.projitems` — content matches
    the generator's output byte-for-byte; only the header comment now
    points at `Documentation/workflow/HowToAddNewApiLevel.md` instead of
    declaring "GENERATED FILE".
  * Repoint the 4 importers (`Mono.Android.targets` x2,
    `create-installers.targets`, `create-android-api.csproj`,
    `Xamarin.Android.Build.Tasks.targets`) at the new path and drop the
    `Condition="Exists(...)"` guards — the file is always present now.
  * Delete `GeneratedMonoAndroidProjitemsFile.cs` and `AndroidPlatform.cs`
    (whole files — `AndroidPlatform` class and `AndroidPlatformExtensions`
    both become unused).
  * Drop the `new GeneratedMonoAndroidProjitemsFile()` registration in
    `Step_GenerateFiles.cs`.
  * Remove `BuildAndroidPlatforms.AllPlatforms` and the now-unused
    `using System.Collections.Generic;`. Keep the NDK constants
    (`AndroidNdkVersion`, `AndroidNdkPkgRevision`, `NdkMinimumAPI`,
    `NdkMinimumAPILegacy32`) — they still have consumers.
  * Update `Documentation/workflow/HowToAddNewApiLevel.md` with the
    XML-based instructions for adding a new API level.
  * Narrow the `build-tools/xaprepare/README.md` blurb for
    `BuildAndroidPlatforms.cs` to NDK metadata.
  * Fix stale doc comment in `GenerateSupportedPlatforms.cs` pointing
    at the old generated path.

Continues the xaprepare cleanup started in PRs #11568 and #11580.

### [docs] Fix Stable=True/False contradiction in HowToAddNewApiLevel

The added prose said Stable should be False for preview API levels, but the
example (CANARY) sets <Stable>True</Stable>, and every entry in
Mono.Android.Apis.projitems is True. Rewrite the prose to match the data and
briefly explain what setting Stable=False would actually do (excludes entry
from default stable framework selection).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [Xamarin.AndroidTools] Remove dead VS Mac / legacy code (#11607)

Context: after the `android-platform-support` repo was inlined here
(see c22cdcf), `src/Xamarin.AndroidTools/` carries a large amount of
code that was only used by old VS Mac / installer / debugger-host
workflows that are no longer part of the .NET for Android product. None
of these types have callers anywhere in this repo, in
`external/xamarin-android-tools/`, or in `external/Java.Interop/`.

Removed (13 files):

  * `PublicationUtilities/PublishAndroidApplication.cs`
  * `PublicationUtilities/PackageSigningTasks.cs`
  * `PublicationUtilities/KeyManagement.cs`
  * `PublicationUtilities/KeystoreEntry.cs`
  * `Sessions/AndroidDeploySession.cs`
  * `Sessions/AndroidConnectCommandSession.cs`
  * `Sessions/AndroidCommandSession.cs`
  * `Sessions/AndroidDeploymentException.cs`
  * `Devices/AndroidPackageList.cs`
  * `Devices/AndroidPackageListExtensions.cs`
  * `Debugging/MonoDroidProcessMonitor.cs`
  * `PlatformPackage.cs`
  * `IProgressNotifier.cs`
  * `AndroidSigningOptions.cs`

Moved (still needed by `ProcessUtils.cs`):

  * `PublicationUtilities/AndroidSdkToolException.cs` ->
    `AndroidSdkToolException.cs` (namespace unchanged)

Pruned from `Devices/AndroidDeviceExtensions.cs` (the methods only
referenced the just-deleted types and had no in-tree callers):

  * `StartActivityWithCommandSession` (used `AndroidCommandSession`)
  * `GetDeploySession`, `GetPackagesAsync`, `GetPackages` (used
    `AndroidDeploySession` / `IProgressNotifier`)
  * `InstallSharedRuntime*` and `InstallSharedPlatform*` overloads
    that took `IProgressNotifier`
  * `GetPackageRemotePath`/`GetPackageRemotePathAsync` (used
    `AndroidDeploymentException`)
  * `GetFastDevRemotePath`/`GetFastDevRemotePathAsync` and the inner
    `FastDevRemotePathInfo` class (only consumer was
    `GetPackageRemotePathAsync`)

Kept methods in `AndroidDeviceExtensions.cs` are the ones still used
by `Xamarin.Android.Build.Debugging.Tasks` (`EnsureProperties`,
`KillProcessAndWaitForExit`, `PushAndInstallPackageAsync`) and by
`DebuggingExtensions` (`SetFastDevPropertyFile`, `GetProcessIDAsync`,
`SetDebugPropertiesAsync`).

Also cleaned up:

  * `Properties/Resources.resx` (English source): removed seven
    `CreateKeyError_*` strings that only `KeyManagement.cs` used.
  * `Properties/Resources.Designer.cs`: removed the seven matching
    properties.
  * `MonoDroidSdk.cs`: two `[Obsolete]` messages referenced the
    now-deleted `PlatformPackage`; changed to `"Do not use."`.

Non-English `Resources.*.resx` and `Localize/loc/**/*.lcl` are left
alone per repo policy (auto-regenerated by OneLocBuild).

Build verified locally:

  * `src/Xamarin.AndroidTools/Xamarin.AndroidTools.csproj`
  * `src/Mono.AndroidTools/Mono.AndroidTools.csproj`
  * `src/Xamarin.Android.Build.Debugging.Tasks/Xamarin.Android.Build.Debugging.Tasks.csproj`
  * `src/Xamarin.Installer.AndroidSDK/Xamarin.Installer.AndroidSDK.csproj`

Net change: -4225 / +2 lines across 19 files.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* [NUnitLite] Add OneTimeSetUp/OneTimeTearDown attribute shims

NUnit 3.x renamed [TestFixtureSetUp]/[TestFixtureTearDown] to [OneTimeSetUp]/[OneTimeTearDown]. dotnet/java-interop#1437 migrated the Java.Interop test suite to the new names.

The bundled Xamarin.Android.NUnitLite (src-ThirdParty/NUnitLite/) only defines the legacy names. Add no-op subclasses for the new names so test source using [OneTimeSetUp]/[OneTimeTearDown] still compiles against bundled NUnitLite once the Java.Interop submodule is bumped past dotnet/java-interop#1437.

These shims become unnecessary once dotnet/android moves off bundled NUnitLite to stock NUnit (tracked in PR #11224).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: VS MobileTools Engineering Service 2 <vsmobiletoolsengsvc2@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers pushed a commit that referenced this pull request Jun 10, 2026
### Bump external/Java.Interop from `e382113` to `b881d21`

Bumps [external/Java.Interop](https://github.com/dotnet/java-interop) from `e382113` to `b881d21`.
- [Commits](dotnet/java-interop@e382113...b881d21)

---
updated-dependencies:
- dependency-name: external/Java.Interop
  dependency-version: b881d21f51cbac6e175de1b2f6c254fe3846aa1d
  dependency-type: direct:production
...

### [NUnitLite] Add OneTimeSetUp/OneTimeTearDown attribute shims

NUnit 3.x renamed [TestFixtureSetUp]/[TestFixtureTearDown] to [OneTimeSetUp]/[OneTimeTearDown]. dotnet/java-interop#1437 migrated the Java.Interop test suite to the new names.

The bundled Xamarin.Android.NUnitLite (src-ThirdParty/NUnitLite/) only defines the legacy names. Add no-op subclasses for the new names so test source using [OneTimeSetUp]/[OneTimeTearDown] still compiles against bundled NUnitLite once the Java.Interop submodule is bumped past dotnet/java-interop#1437.

These shims become unnecessary once dotnet/android moves off bundled NUnitLite to stock NUnit (tracked in PR #11224).

### Bump Irony from 1.1.0 to 1.5.3 (#11561)

---
updated-dependencies:
- dependency-name: Irony
  dependency-version: 1.5.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…od-dotnet-test

Conflict resolutions:
- external/Java.Interop: take main's SHA (this PR does not change the submodule)
- src-ThirdParty/NUnitLite/Attributes/OneTime{SetUp,TearDown}Attribute.cs:
  delete (this PR removes the bundled NUnitLite entirely)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers added a commit that referenced this pull request Jun 10, 2026
Improves reliability of the flaky `JnienvTest.DoNotLeakWeakReferences` test by consolidating three small fixes:

1. **Marshal worker thread exceptions** — capture and re-throw exceptions from the worker `Thread`, so assertion failures inside it produce a real test failure instead of being swallowed.
2. **Allow drift in peer counts** — `Runtime.GetSurfacedObjects()` is process-global, and NUnit/MTP infrastructure (per-test `TestExecutionContext`, listeners, `Console` capture, etc.) creates and releases transient `Java.Lang.Object` peers around every test. Use `Is.EqualTo(...).Within(tolerance)` instead of `Assert.AreEqual` so the count can drift by a few entries between snapshots.
3. **Widen the tolerance to 10** — small bump to account for additional drift seen on slower devices/configurations. A real leak would dwarf this.

Split out of #11224 (branch `jonathanpeppers/dogfood-dotnet-test`) so it can land independently of the larger MTP / `dotnet test` dogfooding work. Only touches `tests/Mono.Android-Tests/Mono.Android-Tests/Java.Interop/JnienvTest.cs`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two unintended changes were introduced by recent merges:

* external/Java.Interop was bumped to b982a1a, but this PR should not
  change the submodule at all. Re-pin to main's b881d21.
* Java.Interop-Tests.NET.csproj had its <Compile Include=...
  JniPeerInstanceMethodsExtensions.cs /> link replaced with a
  <ProjectReference> to Java.Interop.GenericMarshaler.csproj. That
  external project depends on the standalone Java.Interop library,
  while the test project uses the Android platform Java.Interop
  (embedded in Mono.Android.dll). Restore the <Compile> link so the
  helper compiles against the right Java.Interop.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@jonathanpeppers jonathanpeppers merged commit 7ca2231 into main Jun 10, 2026
38 of 40 checks passed
@jonathanpeppers jonathanpeppers deleted the jonathanpeppers/dogfood-dotnet-test branch June 10, 2026 22:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants